package com.exercise.widgets.floatingbutton.floatview

import android.annotation.SuppressLint
import android.app.Activity
import android.widget.FrameLayout
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.contains
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner

@SuppressLint("StaticFieldLeak")
object FloatManager {
    private var mActivity: Activity? = null
    private lateinit var mContentView: FrameLayout
    private var mFloatView: BaseFloatView? = null
    private var mIsShowing = false
    fun with(activity: Activity): FloatManager {
        mActivity = activity
        mContentView = activity.window.decorView.findViewById<FrameLayout>(android.R.id.content)
        addLifecycle(activity)
        return this
    }

    fun add(floatView: BaseFloatView): FloatManager {
        if (mIsShowing) {
            return this
        }
        mFloatView = floatView
        return this
    }

    fun setClickListener(listener: BaseFloatView.OnFloatClickListener): FloatManager {
        mFloatView?.setOnFloatClickListener(listener)
        return this
    }

    private fun addLifecycle(activity: Activity) {
        (activity as? ComponentActivity)?.lifecycle?.addObserver(mLifecycleEventObserver)
    }

    private var mLifecycleEventObserver = LifecycleEventObserver { _, event ->
        if (event == Lifecycle.Event.ON_DESTROY) {
            hide()
        }
    }

    fun show() {
        checkParam()
        if (!mIsShowing) {
            mContentView.removeView(mFloatView)
            mContentView.addView(mFloatView)
            mFloatView?.bringToFront()
            mIsShowing = true
        }
    }

    private fun checkParam() {
        if (mActivity == null) {
            throw NullPointerException("You must be set the 'Activity' params before the show()")
        }
        if (mFloatView == null) {
            throw NullPointerException("You must be set 'FloatView' params before the show()")
        }
    }

    private fun hide() {
        mIsShowing = false
        if (::mContentView.isInitialized && mFloatView != null && mContentView.contains(mFloatView!!)) {
            mContentView.removeView(mFloatView)
        }
        mFloatView?.release()
        mFloatView = null
        (mActivity as? ComponentActivity)?.lifecycle?.removeObserver(mLifecycleEventObserver)
        mActivity = null
    }
}